import { compressImage } from '../utils';
import Queue from '../utils/Queue';
import uploadFetch from '../fetch';

export default function (Vue, options, resultCallback) {
    const { ref } = Vue;
    const { url, limitCount, accept, quality, litmitSize, queueCount } = options;
    return {
        template: `
            <van-uploader v-model="fileList" multiple :after-read="afterRead" :max-count="${limitCount}" :deletable="false"
            accept="${accept.join(',')}" />
        `,
        setup() {
            const fileList = ref([]);
            const changeStatus = (file, status, message) => {
                file.status = status;
                file.message = message;
            }

            const compressedFiles = ref([]);
            const requestArrayArray = ref([]);
            const afterRead = async (file) => {
                if (quality !== 0) {
                    compressedFiles.value = await compress(file);
                    requestArrayArray.value = transformAxios(compressedFiles.value);
                    changeStatus(file, 'uploading', '等待上传');
                } else {
                    requestArrayArray.value = transformAxios(file);
                    changeStatus(file, 'uploading', '等待上传');
                }
                uploadQueue(requestArrayArray.value);
            };

            const compress = async (file) => {
                const compressedUrls = [];
                if (file instanceof Array && file.length !== 0) {
                    const len = file.length;
                    for (let i = 0; i < len; i++) {
                        changeStatus(file[i], 'uploading', '压缩中');
                        const data = await compressImage(file[i], quality, litmitSize);
                        compressedUrls.push(data);
                        changeStatus(file[i], 'uploading', '等待上传');
                    }
                } else {
                    changeStatus(file, 'uploading', '压缩中');
                    const data = await compressImage(file, quality, litmitSize);
                    compressedUrls.push(data);
                    changeStatus(file, 'uploading', '等待上传');
                }
                return compressedUrls;
            };

            const transformAxios = (arr) => {
                const axiosArray = [];
                const len = arr.length;
                for (let i = 0; i < len; i++) {
                    axiosArray.push(BeTagFunction(arr[i], i));
                }

                function BeTagFunction(blob, index) {
                    return {
                        tag: index,
                        fn: async function () {
                            return await uploadFetch(url, blob.file).catch((err) => new Promise.reject(err));
                        }
                    };
                }
                return axiosArray;
            }

            const resultList = [];
            const uploadQueue = (requestArray) => {
                const queue = new Queue(queueCount);
                queue.setOnTaskCompletedCallback((status, completedTaskIndex, result) => {
                    if (status === -1) {
                        // deal error
                        fileList.value[completedTaskIndex].status = 'failed';
                        fileList.value[completedTaskIndex].message = '上传失败';
                        resultList[completedTaskIndex] = result;
                        return;
                    }
                    fileList.value[completedTaskIndex].status = 'done';
                    fileList.value[completedTaskIndex].message = '上传成功';
                    resultList[completedTaskIndex] = result;
                    // result event
                    if (resultList.length === fileList.value.length) {
                        if (resultCallback) {
                            resultCallback(resultList)
                        }
                    }
                });
                queue.addList(requestArray);
                queue.run();
            }

            return { fileList, afterRead }
        }
    }
}